import axios from 'axios';
import { MessageBox, Message } from 'element-ui';
// eslint-disable-next-line import/no-cycle
import router from '@/router';

import UrlMap from './urlMap.js';
import { SUCCESS } from './response.code.conf';

// 请求超时时间
axios.defaults.timeout = 50000;

// content-type headers
const ContentType = {
  get: 'application/json;charset=UTF-8',
  post: 'application/x-www-form-urlencoded;charset=UTF-8',
  file: 'multipart/form-data;charset=UTF-8',
  xml: 'text/xml;charset=UTF-8'
};

class Http {
  constructor() {
    this.config = {
      headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        'x-authtoken': window.localStorage.getItem('token') || ''
      }
    };
  }

  /**
   * 获取url
   * @param {*} param0
   */
  getRealUrl({ map, url }) {
    return process.env.VUE_APP_BASE_URL + UrlMap[map][url];
  }

  /**
   * 设置contact-type
   * @param {*} type string get|post|file|xml
   */
  setContentType(type) {
    this.config.headers['Content-Type'] = ContentType[type];
  }

  /**
   * 设置常规headers头（如token）
   * @param {*} headers object{}
   */
  setHeaders(headers) {
    Object.assign(this.config.headers, headers);
  }

  /**
   * axios 错误处理
   * @param {*} err
   */
  errorHandel(err, reject) {
    // console.error(err.response);

    const { status } = err.response;
    let { message } = err.response.data;

    message = message ? message : '服务器异常';

    switch (status) {
      case 403:
        Message({
          type: 'error',
          message
        });
        break;
      case 404:
        Message({
          type: 'error',
          message
        });
        break;
      case 500:
        Message({
          type: 'error',
          message
        });
        break;
      default:
        break;
    }

    reject(err);
  }

  /**
   * get 请求(base)
   * @param {*} url string| object {map,url}
   * @param {*} params 参数object
   * @param {*} config 配置object
   */
  get(url, params = {}, config) {
    // 获取真实的url
    const _url = typeof url === 'string' ? url : this.getRealUrl(url);

    return new Promise((resolve, reject) => {
      this.setContentType('get');
      Object.assign(this.config, config);
      axios
        .get(_url, { params, headers: this.config['headers'] })
        .then(res => {
          // console.log(res);
          const { data } = res;
          if (data['code'] === SUCCESS) {
            // console.log(res);
            resolve(res);
          } else {
            if (!data['success']) {
              if (data['code'] !== 10106) {
                Message({
                  type: 'error',
                  message: data['msg']
                });
              }
            }
            resolve(res);
          }
        })
        .catch(err => {
          // console.log('err');
          this.errorHandel(err, reject);
        });
    });
  }

  /**
   * post 请求(base)
   * @param {*} url string | object{map,url}
   * @param {*} params 参数object
   * @param {*} config 配置
   */
  post(url, params = {}, config = {}) {
    // 获取真实的url
    const _url = typeof url === 'string' ? url : this.getRealUrl(url);

    return new Promise((resolve, reject) => {
      this.setContentType('post');
      /**
       * data form stringify
       */
      let formData = '';
      // eslint-disable-next-line guard-for-in
      for (let it in params) {
        if (typeof params[it] === 'object') {
          params[it] = JSON.stringify(params[it]);
        }
        formData += encodeURIComponent(it) + '=' + encodeURIComponent(params[it]) + '&';
      }

      formData = formData.substr(0, formData.length - 1);

      this.setHeaders(config);
      axios
        .post(_url, formData, this.config)
        .then(res => {
          const { data } = res;
          // 过期code
          if (data.code === 10303) {
            router.push({ name: 'login' });
            return;
          }
          resolve(res);
          // unsuccess
          if (data['success'] === false) {
            if (data['code'] !== 10106) {
              Message({
                type: 'error',
                message: data['msg']
              });
            }
          }
        })
        .catch(err => {
          // console.log("http error", err);
          if (url.url === 'times') {
            reject(err);
            return;
          }
          this.errorHandel(err, reject);
        });
    });
  }

  file(url, params) {
    // 获取真实的url
    const _url = typeof url === 'string' ? url : this.getRealUrl(url);
    return new Promise((resolve, reject) => {
      this.setContentType('file');
      axios
        .post(_url, params, this.config)
        .then(res => {
          if (res.data['code'] === SUCCESS) {
            resolve(res);
          } else {
            resolve(res);
          }
        })
        .catch(err => {
          this.errorHandel(err, reject);
        });
    });
  }

  /**
   * 文件下载
   * @param {*} url
   * @param {*} params
   */

  downFile(url, params, fileName = '下载文件') {
    // 获取真实的url
    const _url = typeof url === 'string' ? url : this.getRealUrl(url);

    /**
     * data form stringify
     */
    let formData = '';
    // eslint-disable-next-line guard-for-in
    for (let it in params) {
      if (typeof params[it] === 'object') {
        params[it] = JSON.stringify(params[it]);
      }
      formData += encodeURIComponent(it) + '=' + encodeURIComponent(params[it]) + '&';
    }

    formData = formData.substr(0, formData.length - 1);
    return new Promise((resolve, reject) => {
      axios({
        method: 'post',
        url: _url,
        data: formData,
        responseType: 'blob',
        headers: {
          'X-AuthToken': window.localStorage.getItem('token')
        }
      })
        .then(data => {
          // console.log(data);
          // const { headers } = data;
          // // console.log(headers);
          // const fileName = headers['content-disposition'].split ?
          //   headers['content-disposition'].split('=')[1] :
          //   '下载文件.xlsx';

          if (!data) {
            reject(data);
            return;
          }
          if (data['status'] === 200) {
            let linkUrl = window.URL.createObjectURL(new Blob([data.data])),
              link = document.createElement('a');
            link.style.display = 'none';
            link.href = linkUrl;
            link.setAttribute('download', fileName + '.xlsx');
            document.body.appendChild(link);
            link.click();
            resolve(true);
          } else {
            reject(data.data);
          }
        })
        .catch(err => {
          this.errorHandel(err, reject);
        });
    });
  }

  xml() {}

  loading() {}

  /**
   * 删除 delete http request
   * @param {*} url url string
   * @param {*} params params object
   * @param {*} param2 提示信息{title:string,message:string}
   */
  delete(
    url,
    params = {},
    { title, message, text } = {
      title: '删除提示',
      message: '此操作将永久删除, 是否继续?',
      text: '删除成功!'
    }
  ) {
    return new Promise((resolve, reject) => {
      MessageBox.confirm(message, title, {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.post(url, params)
            .then(res => {
              Message({
                type: 'success',
                message: text
              });
              resolve(res);
            })
            .catch(err => {
              Message({
                type: 'error',
                message: err.data['msg']
              });
              reject(err);
            });
        })
        .catch(err => {
          Message({
            type: 'info',
            message: '已取消操作!'
          });
        });
    });
  }

  put(url, params = {}) {
    return new Promise((resolve, reject) => {
      this.post(url, params)
        .then(res => {
          Message({
            type: 'success',
            message: '新增成功!'
          });
          resolve(res);
        })
        .catch(err => {
          Message({
            type: 'error',
            message: err.data['msg']
          });
          reject(err);
        });
    });
  }

  update(url, params) {
    return new Promise((resolve, reject) => {
      this.post(url, params)
        .then(res => {
          if (res.data['code'] === SUCCESS) {
            Message({
              type: 'success',
              message: '修改成功!'
            });
            resolve(res);
          } else {
            Message({
              type: 'error',
              message: res.data['msg']
            });
            reject(res);
          }
        })
        .catch(err => {
          Message({
            type: 'error',
            message: err.data['msg']
          });
          reject(err);
        });
    });
  }

  /**
   * 统计
   * @param {*} url
   * @param {*} params
   */
  log(url, params) {
    // 获取真实的url
    const _url = typeof url === 'string' ? url : this.getRealUrl(url);

    // const blob = new Blob(request, this.config.headers);
    // if (navigator.sendBeacon) {
    //   navigator.sendBeacon(_url, params);
    // } else {
    const client = new XMLHttpRequest();
    client.open('POST', _url, false); // 第三个参数表明是同步的 xhr
    this.setContentType('post');
    // eslint-disable-next-line guard-for-in
    for (let key in this.config.headers) {
      client.setRequestHeader(key, this.config.headers[key]);
    }

    // client.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');

    let formData = '';
    // eslint-disable-next-line guard-for-in
    for (let it in params) {
      if (typeof params[it] === 'object') {
        params[it] = JSON.stringify(params[it]);
      }
      formData += encodeURIComponent(it) + '=' + encodeURIComponent(params[it]) + '&';
    }

    formData = formData.substr(0, formData.length - 1);

    client.send(formData);
  }
  // }
}

export default Http;
